package modelo.servicios;

import java.util.ArrayList;
import modelo.fabricas.FabricaDeTuberias;
import modelo.interfaces.ConstruibleTerrestre;
import modelo.interfaces.ConsumidorDeAgua;
import modelo.interfaces.Persistible;
import modelo.mapa.Mapa;
import modelo.mapa.Ubicacion;

public class PozoDeAgua implements Persistible {

    private static int costo;       
    private Ubicacion ubicacion;    
    private ArrayList<RedDeAgua> redesDeAgua;
    
    public PozoDeAgua()
    {
        costo = 250;
        this.redesDeAgua = new ArrayList<RedDeAgua>();
    }
    
    public ArrayList<RedDeAgua> obtenerRedesDeAgua()
    {
        return this.redesDeAgua;
    }
    
    public static int obtenerCosto()
    {
        return costo;
    }

    public void asignarUbicacion(Ubicacion unaUbicacion)
    {               
        this.ubicacion = unaUbicacion;
    }
    
    
    public Ubicacion obtenerUbicacion ()
    {
        return this.ubicacion;
    }

    public void comenzarRedDeAgua(Ubicacion ubicacionTuberiaDeAgua) 
    {
        FabricaDeTuberias fabrica = new FabricaDeTuberias();
        TuberiaDeAgua tuberiaDeAgua = fabrica.crearTuberiaDeAgua(ubicacionTuberiaDeAgua);       
        RedDeAgua redDeAgua = new RedDeAgua(this);
        this.redesDeAgua.add(redDeAgua);
        redDeAgua.obtenerListaDeTuberias().add(tuberiaDeAgua);
        tuberiaDeAgua.asignarRedDeAgua(redDeAgua);                                      
    }       
    
    public boolean continuarRedDeAgua(Ubicacion ubicacionNuevaTuberiaDeAgua) 
    {
        boolean seContinuoLaRed = false;
        for(RedDeAgua redDeAgua : this.redesDeAgua)
        {
            if(!redDeAgua.obtenerListaDeTuberias().isEmpty() && (!seContinuoLaRed))
            {
                Ubicacion ubicacionUltimaTuberiaDeAgua = redDeAgua.obtenerListaDeTuberias().get(redDeAgua.obtenerListaDeTuberias().size()-1).obtenerUbicacion();
                if(Mapa.getInstance().sonLimitrofes(ubicacionNuevaTuberiaDeAgua,ubicacionUltimaTuberiaDeAgua))
                {
                    FabricaDeTuberias fabrica = new FabricaDeTuberias();
                    TuberiaDeAgua tuberiaDeAgua = fabrica.crearTuberiaDeAgua(ubicacionNuevaTuberiaDeAgua);  
                    redDeAgua.obtenerListaDeTuberias().add(tuberiaDeAgua);
                    tuberiaDeAgua.asignarRedDeAgua(redDeAgua);
                    seContinuoLaRed = true;
                }
            }                       
        }        
        return seContinuoLaRed;
    }

    public void abastecerALosEdificiosLimitrofesDeLaRed() 
    {       
        ConstruibleTerrestre construccionAAbastecer;
        ArrayList<Ubicacion> ubicacionesLimitrofes;
        for (RedDeAgua redDeAgua : this.redesDeAgua)
        {
            for (TuberiaDeAgua tuberiaDeAgua : redDeAgua.obtenerListaDeTuberias())
            {
                ubicacionesLimitrofes = Mapa.getInstance().obtenerUbicacionesLimitrofes(tuberiaDeAgua.obtenerUbicacion());
                for (Ubicacion ubicacionLimitrofeATuberia : ubicacionesLimitrofes)
                {
                    construccionAAbastecer =  Mapa.getInstance().obtenerHectareaSegunUbicacion(ubicacionLimitrofeATuberia).obtenerConstruccionTerrestre();
                    this.brindarServicio(construccionAAbastecer);
                }
            }
        }
    }

    private void brindarServicio(ConstruibleTerrestre unaConstruccionTerrestre) 
    {
        if((unaConstruccionTerrestre != null) && (unaConstruccionTerrestre.consumeAgua()==true) && (unaConstruccionTerrestre.obtenerPozoQueAbastece() == null ) )
        {
            //si estamos dentro del if es porque en la hectarea hay una construccion que necesita agua y todavia no la tiene
            ConsumidorDeAgua consumidorDeAgua = (ConsumidorDeAgua)unaConstruccionTerrestre;
            consumidorDeAgua.asignarPozoDeAgua(this);
        }
    }

    public boolean tieneAgua() 
    {
        return true;
    }

	public boolean abastezcoAConstruccion(ConstruibleTerrestre construibleTerrestre) 
	{
		ConstruibleTerrestre construccionAAbastecer;
        ArrayList<Ubicacion> ubicacionesLimitrofes;
        for (RedDeAgua redDeAgua : this.redesDeAgua)
        {
            for (TuberiaDeAgua tuberiaDeAgua : redDeAgua.obtenerListaDeTuberias())
            {
                ubicacionesLimitrofes = Mapa.getInstance().obtenerUbicacionesLimitrofes(tuberiaDeAgua.obtenerUbicacion());
                for (Ubicacion ubicacionLimitrofeATuberia : ubicacionesLimitrofes)
                {
                    construccionAAbastecer =  Mapa.getInstance().obtenerHectareaSegunUbicacion(ubicacionLimitrofeATuberia).obtenerConstruccionTerrestre();
                    if((construccionAAbastecer == construibleTerrestre) && (construccionAAbastecer.obtenerPozoQueAbastece() == this))
                    {
                    	return true;
                    }
                }
            }
        }
        return false;
	}

	@Override
	public ArrayList obtenerDatosPersistibles()
	{
		ArrayList<Object> elems=new ArrayList<Object>();
		elems.add(this.ubicacion);
		elems.add(this.redesDeAgua);
		return elems;
	}

	@Override
	public void poblar(ArrayList elementos)
	{
		this.ubicacion=(Ubicacion) elementos.get(0);
		this.redesDeAgua=(ArrayList<RedDeAgua>) elementos.get(1);		
	}
}